#!/bin/bash

# Kexilo 代码质量检查脚本
# 用于在提交代码前进行全面的代码质量检查

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 日志函数
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 检查Maven是否可用
check_maven() {
    if ! command -v mvn &> /dev/null; then
        log_error "Maven未安装或不在PATH中"
        exit 1
    fi
    log_info "Maven版本: $(mvn -version | head -1)"
}

# 编译检查
compile_check() {
    log_info "开始编译检查..."
    if mvn clean compile -q; then
        log_success "编译检查通过"
    else
        log_error "编译检查失败"
        exit 1
    fi
}

# 代码格式化检查
format_check() {
    log_info "开始代码格式化检查..."
    if mvn spotless:check -q; then
        log_success "代码格式化检查通过"
    else
        log_warning "代码格式化检查失败，尝试自动修复..."
        if mvn spotless:apply -q; then
            log_success "代码格式化已自动修复"
        else
            log_error "代码格式化修复失败"
            return 1
        fi
    fi
}

# CheckStyle检查
checkstyle_check() {
    log_info "开始CheckStyle检查..."
    if mvn checkstyle:check -q; then
        log_success "CheckStyle检查通过"
    else
        log_error "CheckStyle检查失败"
        log_info "查看详细报告: target/checkstyle-result.xml"
        return 1
    fi
}

# PMD检查
pmd_check() {
    log_info "开始PMD静态分析..."
    if mvn pmd:check -q; then
        log_success "PMD检查通过"
    else
        log_error "PMD检查失败"
        log_info "查看详细报告: target/pmd.xml"
        return 1
    fi
}

# SpotBugs检查
spotbugs_check() {
    log_info "开始SpotBugs检查..."
    if mvn spotbugs:check -q; then
        log_success "SpotBugs检查通过"
    else
        log_error "SpotBugs检查失败"
        log_info "查看详细报告: target/spotbugsXml.xml"
        return 1
    fi
}

# OWASP依赖检查
owasp_check() {
    log_info "开始OWASP依赖安全检查..."
    if mvn org.owasp:dependency-check-maven:check -q; then
        log_success "OWASP依赖检查通过"
    else
        log_warning "OWASP依赖检查发现安全问题"
        log_info "查看详细报告: target/dependency-check-report.html"
        return 1
    fi
}

# 测试覆盖率检查
coverage_check() {
    log_info "开始测试和覆盖率检查..."
    if mvn test jacoco:report -q; then
        log_success "测试和覆盖率检查完成"
        log_info "查看覆盖率报告: target/site/jacoco/index.html"
    else
        log_error "测试执行失败"
        return 1
    fi
}

# SonarQube本地分析（可选）
sonar_check() {
    if [ "$SONAR_LOCAL" = "true" ]; then
        log_info "开始SonarQube本地分析..."
        if mvn sonar:sonar -Dsonar.host.url=http://localhost:9000 -q; then
            log_success "SonarQube分析完成"
        else
            log_warning "SonarQube分析失败（可能是服务未启动）"
        fi
    fi
}

# 生成质量报告汇总
generate_summary() {
    log_info "生成质量检查报告汇总..."
    
    REPORT_FILE="quality-report-$(date +%Y%m%d-%H%M%S).txt"
    
    cat > "$REPORT_FILE" << EOF
Kexilo 代码质量检查报告
生成时间: $(date)
检查范围: 全部模块

=== 检查结果汇总 ===
编译检查: $COMPILE_STATUS
格式化检查: $FORMAT_STATUS
CheckStyle检查: $CHECKSTYLE_STATUS
PMD检查: $PMD_STATUS
SpotBugs检查: $SPOTBUGS_STATUS
OWASP检查: $OWASP_STATUS
测试覆盖率: $COVERAGE_STATUS

=== 详细报告位置 ===
CheckStyle: target/checkstyle-result.xml
PMD: target/pmd.xml
SpotBugs: target/spotbugsXml.xml
OWASP: target/dependency-check-report.html
测试覆盖率: target/site/jacoco/index.html

=== 建议 ===
1. 修复所有BLOCKER和CRITICAL级别的问题
2. 逐步改善MAJOR级别的问题
3. 保持测试覆盖率在80%以上
4. 定期更新依赖版本以修复安全漏洞
EOF

    log_success "质量报告已生成: $REPORT_FILE"
}

# 主函数
main() {
    echo "========================================"
    echo "    Kexilo 代码质量检查工具"
    echo "========================================"
    
    # 解析命令行参数
    SKIP_COMPILE=false
    SKIP_FORMAT=false
    SKIP_TESTS=false
    QUICK_MODE=false
    SONAR_LOCAL=false
    
    while [[ $# -gt 0 ]]; do
        case $1 in
            --skip-compile)
                SKIP_COMPILE=true
                shift
                ;;
            --skip-format)
                SKIP_FORMAT=true
                shift
                ;;
            --skip-tests)
                SKIP_TESTS=true
                shift
                ;;
            --quick)
                QUICK_MODE=true
                shift
                ;;
            --sonar)
                SONAR_LOCAL=true
                shift
                ;;
            --help)
                echo "用法: $0 [选项]"
                echo "选项:"
                echo "  --skip-compile  跳过编译检查"
                echo "  --skip-format   跳过格式化检查"
                echo "  --skip-tests    跳过测试"
                echo "  --quick         快速模式（跳过耗时检查）"
                echo "  --sonar         运行SonarQube本地分析"
                echo "  --help          显示此帮助信息"
                exit 0
                ;;
            *)
                log_error "未知选项: $1"
                exit 1
                ;;
        esac
    done
    
    # 初始化状态变量
    COMPILE_STATUS="SKIPPED"
    FORMAT_STATUS="SKIPPED"
    CHECKSTYLE_STATUS="SKIPPED"
    PMD_STATUS="SKIPPED"
    SPOTBUGS_STATUS="SKIPPED"
    OWASP_STATUS="SKIPPED"
    COVERAGE_STATUS="SKIPPED"
    
    # 执行检查
    check_maven
    
    if [ "$SKIP_COMPILE" = false ]; then
        if compile_check; then
            COMPILE_STATUS="PASSED"
        else
            COMPILE_STATUS="FAILED"
        fi
    fi
    
    if [ "$SKIP_FORMAT" = false ]; then
        if format_check; then
            FORMAT_STATUS="PASSED"
        else
            FORMAT_STATUS="FAILED"
        fi
    fi
    
    if checkstyle_check; then
        CHECKSTYLE_STATUS="PASSED"
    else
        CHECKSTYLE_STATUS="FAILED"
    fi
    
    if [ "$QUICK_MODE" = false ]; then
        if pmd_check; then
            PMD_STATUS="PASSED"
        else
            PMD_STATUS="FAILED"
        fi
        
        if spotbugs_check; then
            SPOTBUGS_STATUS="PASSED"
        else
            SPOTBUGS_STATUS="FAILED"
        fi
        
        if owasp_check; then
            OWASP_STATUS="PASSED"
        else
            OWASP_STATUS="FAILED"
        fi
    fi
    
    if [ "$SKIP_TESTS" = false ]; then
        if coverage_check; then
            COVERAGE_STATUS="PASSED"
        else
            COVERAGE_STATUS="FAILED"
        fi
    fi
    
    # SonarQube分析
    sonar_check
    
    # 生成报告
    generate_summary
    
    # 检查总体结果
    FAILED_CHECKS=0
    [ "$COMPILE_STATUS" = "FAILED" ] && ((FAILED_CHECKS++))
    [ "$FORMAT_STATUS" = "FAILED" ] && ((FAILED_CHECKS++))
    [ "$CHECKSTYLE_STATUS" = "FAILED" ] && ((FAILED_CHECKS++))
    [ "$PMD_STATUS" = "FAILED" ] && ((FAILED_CHECKS++))
    [ "$SPOTBUGS_STATUS" = "FAILED" ] && ((FAILED_CHECKS++))
    [ "$OWASP_STATUS" = "FAILED" ] && ((FAILED_CHECKS++))
    [ "$COVERAGE_STATUS" = "FAILED" ] && ((FAILED_CHECKS++))
    
    echo "========================================"
    if [ $FAILED_CHECKS -eq 0 ]; then
        log_success "所有代码质量检查通过！"
        exit 0
    else
        log_error "有 $FAILED_CHECKS 项检查失败，请修复后重新提交"
        exit 1
    fi
}

# 执行主函数
main "$@"
